﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using facebook;

namespace Veracruz.Facebook.Data
{
    public static class UsersAssociation  // TODO : Change access modifier to internal
    {
        #region consts

        public const string Name = "users";
        public const string ApplicationId = "application_id";
        public const string UserId = "uid";
        public const string GetUserIds = "select uid from app.users where application_id={0}";
        public const string GetUserIdByEmail = "select uid from app.users where application_id={0} and _data='{1}'";
        public const string GetUserIdByFullName = "SELECT uid FROM user WHERE name = '{1}' AND uid IN (SELECT uid FROM app.users WHERE application_id={0})";
        public const string GetAllUserIds = "SELECT uid, _data FROM app.users WHERE application_id={0} ORDER BY uid LIMIT {1} OFFSET {2}";
        public const string GetAllUserIdsByEmail = "SELECT uid, _data FROM app.users WHERE application_id={0} AND strpos(substr(_data, 0, strpos(_data,'@')), '{1}')=0 ORDER BY _data LIMIT {2} OFFSET {3}";
        public const string GetAllUserIdsByFullName = "SELECT uid FROM user WHERE name = '{1}' AND uid IN (SELECT uid FROM app.users WHERE application_id={0}) ORDER BY uid LIMIT {2} OFFSET {3}";
        

        #endregion
        #region methods

        internal static void Reset(Session session)
        {
            // users uid ---> application_id unique
            API l_api = FacebookHelper.CreateAPI(session);
            l_api.data.undefineAssociation(Name);

            //users uid ---> application_id unique  
            //            integer  assoc_type  Type of this association: 
            //1: one-way association, where reverse lookup is not needed; 
            //2: two-way symmetric association, where a backward association (B to A) is always created when a forward association (A to B) is created. 
            //3: two-way asymmetric association, where a backward association (B to A) has different meaning than a forward association (A to B).  
            //l_api.data.defineAssociation(Name, );
            facebook.Schema.assoc_object_type l_obj1 = new facebook.Schema.assoc_object_type();
            l_obj1.alias = ApplicationId;
            l_obj1.object_type = string.Empty;
            //l_obj1.unique = true;
            facebook.Schema.assoc_object_type l_obj2 = new facebook.Schema.assoc_object_type();
            l_obj2.alias = UserId;
            l_obj2.object_type = string.Empty;
            //l_obj2.unique = false;
            l_api.data.defineAssociation(Name, 1, l_obj1, l_obj2, null);
        }       

        #endregion
        #region queries

        public static class Queries
        {
            public static string GetUserIdByFullName(string userName)
            {
                return string.Format(UsersAssociation.GetUserIdByFullName, Constants.ApplicationId, userName);
            }
            public static string GetUserIdByEmail(string email)
            {
                return string.Format(UsersAssociation.GetUserIdByEmail, Constants.ApplicationId, email);
            }
            public static string GetAllUserIdentities(int pageIndex, int pageSize)
            {
                return string.Format(UsersAssociation.GetAllUserIds, Constants.ApplicationId, pageSize, pageIndex);
            }
            public static string GetAllUserIdentitiesByEmail(string emailToMatch, int pageIndex, int pageSize)
            {
                return string.Format(UsersAssociation.GetAllUserIdsByEmail, Constants.ApplicationId, emailToMatch, pageSize, pageIndex);
            }

            public static string GetAllUserIdentitiesByFullName(string fullNameToMatch, int pageIndex, int pageSize)
            {
                return string.Format(UsersAssociation.GetAllUserIdsByFullName, Constants.ApplicationId, fullNameToMatch, pageSize, pageIndex);
            }
        }

        #endregion
    }
}
